package com.tg.sieve_data.interceptor;

import com.google.gson.Gson;
import com.tg.sieve_data.annotation.AccessCheck;
import com.tg.sieve_data.common.Result;
import com.tg.sieve_data.controller.sys.UserIdHolder;
import com.tg.sieve_data.entity.sys.SysUserTokenEntity;
import com.tg.sieve_data.mapper.sys.SysUserTokenMapper;
import com.tg.sieve_data.utils.HttpContextUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;

public class OAuth2Interceptor implements HandlerInterceptor {
    private final SysUserTokenMapper sysUserTokenMapper;

    public OAuth2Interceptor(SysUserTokenMapper sysUserTokenMapper) {
        this.sysUserTokenMapper = sysUserTokenMapper;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = getRequestToken(request);
        SysUserTokenEntity sysUserTokenEntity = sysUserTokenMapper.queryByToken(token);
        if (sysUserTokenEntity != null  ) {
            UserIdHolder.setUserId(sysUserTokenEntity.getUserId());
        }
        if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            return true;
        }

        // 检查方法是否有自定义注解
        boolean hasCustomAnnotation = checkMethodForAnnotation(handler);
        if (! hasCustomAnnotation) {
            // 处理带有注解的逻辑
            return true;
        }

        // 获取请求 token，如果 token 不存在，直接返回 401
        if (StringUtils.isBlank(token)) {
            sendUnauthorizedResponse(response);
            return false;
        }

        return true;
    }

    private boolean checkMethodForAnnotation(Object handler) {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            return method.isAnnotationPresent(AccessCheck.class);
        }
        return false;
    }

    private String getRequestToken(HttpServletRequest httpRequest) {
        String token = httpRequest.getHeader("token");
        if (StringUtils.isBlank(token)) {
            token = httpRequest.getParameter("token");
        }
        return token;
    }

    private void sendUnauthorizedResponse(HttpServletResponse response) throws IOException {
        sendUnauthorizedResponse(response, "invalid token");
    }

    private void sendUnauthorizedResponse(HttpServletResponse response, String message) throws IOException {
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin());
        response.setContentType("application/json;charset=utf-8");
        String json = new Gson().toJson(Result.error(401, message));
        response.getWriter().print(json);
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 请求处理完成后清除 userId
        UserIdHolder.clear();
    }
}
